package GUI;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Label;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Listener;


import java.awt.Toolkit;
import java.io.InputStream;
import java.lang.String;

import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;

import backend.CommandInput;
import backend.Task;

/**The View and Controller part of the program, get user action to update the model
 * and pull latest data from model to display back to user.
 * It has 3 separate thread doing realtime display, periodic task saves, and 
 * checking for overdue tasks.
 * @author Defeng
 *
 */
public class GUI extends Composite {
	private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
	private final win32KeyHook hook;
	private Image logo;
	//private ArrayList<String> inputCache;

	//used by inputCmdBox
	private Text inputCmdBox;
	//used by helperMsgView
	private List helperMsgList = null; 
	private ArrayList<String> modelOutput_HM = null; 
	//used by Task Count Box
	private List taskCountList = null;
	private int overdueCount, doneCount, uncompletedCount;
	//used by Main Task Display Table View
	private Table mainTaskDisplayTable;
	private TableColumn[] mainTaskDisplayColumns = null;
	private int taskidx=0;
	private ArrayList<Task> modelOutput_MTD = null;	//modelOutput_MTDcopied = null; 
	private TaskComparator comparator;
	//used by Legend Table
	private TableColumn[] legendColumns=null;
	//used by Syntax Hint Box
	private Label syntaxHints;

	/**Constructor for the GUI class
	 * @param parent
	 * @param style
	 */
	public GUI(Composite parent, int style) {
		super(parent, SWT.BORDER);
		final Shell shell = parent.getShell();
		final Display display = parent.getDisplay();
		hook = new win32KeyHook(shell, display);
				
		initModel();
		
		createMainFrame(shell);
		createMenuBar(shell);
		createInputCmdBoxLabel(this);
		createInputCmdBox(this);
		createSyntaxHintBox(this);
		createTimeDisplay(this);
		createLogo(this);
		createHelperMsgBox(this);
	    createTaskCountBox(this);
		createLegendBox(this);
		createMainTaskDisplay();
		setTabList(new Control[]{inputCmdBox, mainTaskDisplayTable});
		
		beginPeriodicSave(this);
		beginOverdueCheck(shell);
	} 
	
	/**The Listener Action when dispose is called on shell
	 *
	 */
	private void shellDisposedAction(DisposeEvent e, Composite parent) {
		CommandInput.staticInput.parseCmd("save");
		toolkit.dispose();
		hook.removeHook(parent);
	}
	/**The Listener Action for menu1_1
	 *
	 */
	private void menu1_1Action(Event e){
		CommandInput.staticInput.parseCmd("save");
    	helperMsgList.removeAll();
    	helperMsgList.add("Successfully Saved");
	}
	/**The Listener Action for menu2_1
	 *
	 */
	private void menu2_1Action(Event e){
		CommandInput.staticInput.parseCmd("view all");
		inputCmdBox.setText("view all");
		inputCmdBox.selectAll();
		modelChangeViaCmdLn();
		refreshView_HM();
		refreshView_MTDTable();
	}
	/**The Listener Action for menu2_2
	 *
	 */
	private void menu2_2Action(Event e){
		taskCountList.removeAll();
		CommandInput.staticInput.parseCmd("view upcoming 10");
		refreshView_MTDTable();
	}
	/** Initialize the model and populate view with data
	 * 	
	 */
	private void initModel(){
		CommandInput.initInput();
		CommandInput.staticInput.parseCmd("import ~");
		//CommandInput.staticInput.parseCmd("+* #160213 @1000-1200 :Study CS2103 exam $NUS");
		//CommandInput.staticInput.parseCmd("+* #160413 @1200-1200 CS2103 exam no label $NUS");
		//CommandInput.staticInput.parseCmd("+* #160613 @1000-1200 CS2103 $NUS");
		//CommandInput.staticInput.parseCmd("+ #030511 @0800-1000 run 15 May 8am-10am $bishanpark !off");
		//CommandInput.staticInput.parseCmd("+* #051111 @1900-2000 :Faith mybirthday at church $church");
		//outputGUI.clear();
		
		CommandInput.staticInput.parseCmd("view all");
		modelOutput_MTD = CommandInput.staticInput.outTable();
		//viewListGUIcopied = new ArrayList(output);
		modelOutput_HM = CommandInput.staticInput.out();
		modelOutput_HM.clear();
	}
	
	/**	Creates the main frame of the program
	 *
	 */
	private void createMainFrame(final Composite parent){
		parent.getShell().setText("Remember4Me - v0.2");
		setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
		setSize(new Point(815, 441));
		//toolkit.adapt(this);
		//toolkit.paintBordersFor(this);
		toolkit.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		setLayout(null);
		addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				shellDisposedAction(e, parent);
			}
		});
	}
	
	/**Creates the top MenuBar
	 *
	 */
	private void createMenuBar(final Shell parent){
		final Menu mbar = new Menu(parent,SWT.BAR );
		parent.setMenuBar(mbar);
		
        //create a File menu
        final MenuItem menu1 = new MenuItem(mbar, SWT.CASCADE);
        menu1.setText("&File");
        final Menu menu1_container = new Menu(parent, SWT.DROP_DOWN);
        menu1.setMenu(menu1_container);
        final MenuItem menu1_1 = new MenuItem(menu1_container, SWT.PUSH);
        menu1_1.setText("&Save to File\tCTRL+S");
        menu1_1.setAccelerator(SWT.CTRL+'S');
        menu1_1.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
            	menu1_1Action(event);
              }
            });
        final MenuItem menu1separator1 = new MenuItem(menu1_container, SWT.SEPARATOR);
        final MenuItem menu1_2 = new MenuItem(menu1_container, SWT.PUSH);
        menu1_2.setText("E&xit");
        menu1_2.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
            	parent.dispose();
            }
        });
        
        //create a Window menu
        final MenuItem menu2 = new MenuItem(mbar, SWT.CASCADE);
        menu2.setText("&View");
        final Menu menu2_container = new Menu(parent, SWT.DROP_DOWN);
        menu2.setMenu(menu2_container);
        final MenuItem menu2_1 = new MenuItem(menu2_container, SWT.PUSH);
        menu2_1.setText("by&Date\tCTRL+1");
        menu2_1.setAccelerator(SWT.CTRL+'1');
        menu2_1.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
            	menu2_1Action(event);
              }
            });
        final MenuItem menu2_2 = new MenuItem(menu2_container, SWT.PUSH);
        menu2_2.setText("&Next10\tCTRL+2");
        menu2_2.setAccelerator(SWT.CTRL+'2');
        menu2_2.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                menu2_2Action(event);
              }
            });
	}
	
	/**Creates the Command Input Box for userInput
	 *
	 */
	private void createInputCmdBox(Composite parent){
		inputCmdBox = new Text(parent, SWT.BORDER);
		inputCmdBox.setBounds(113, 33, 464, 25);
		inputCmdBox.setText("What can I do for you? =)");
		inputCmdBox.selectAll();
		inputCmdBox.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
		toolkit.adapt(inputCmdBox, true, true);
		inputCmdBox.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				inputBoxKeyReleasedAction(e);
			}
		});
	}
	
	/**Creates the label for InputCmdBox
	 *
	 */
	private void createInputCmdBoxLabel(Composite parent){
		Label inputCmdLabel = new Label(parent, SWT.NONE);
		inputCmdLabel.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
		inputCmdLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
		inputCmdLabel.setForeground(SWTResourceManager.getColor(255, 255, 255));
		inputCmdLabel.setBounds(28, 37, 79, 18);
		inputCmdLabel.setText("Command:");
		//inputCmdLabel.setFont(SWTResourceManager.getFont("Lucida Grande", 12, SWT.NORMAL));
		//toolkit.adapt(inputCmdLabel, true, true);
	}
	
	/**Creates the helper message box which displays information
	 * about task actions, errors on command failure.
	 *
	 */
	private void createHelperMsgBox(Composite parent){
		ListViewer helperMsgViewer = new ListViewer(parent, SWT.NONE);
		helperMsgList = helperMsgViewer.getList();
		helperMsgList.setForeground(SWTResourceManager.getColor(0, 255, 0));
		helperMsgList.setBackground(SWTResourceManager.getColor(0, 0, 0));
		helperMsgList.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.NORMAL));
		helperMsgList.setBounds(587, 163, 230, 30);
		//toolkit.adapt(dialogList, true, true);
	}
	
	/**Create syntax hint box to help user know the correct syntax that 
	 * command input box accepts
	 *
	 */
	private void createSyntaxHintBox(Composite parent){
		syntaxHints = new Label(parent, SWT.NONE);
		syntaxHints.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
		syntaxHints.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		syntaxHints.setBounds(28, 64, 514, 23);
		//cmdHints.setFont(SWTResourceManager.getFont("Lucida Grande", 12, SWT.NORMAL));
		//toolkit.adapt(cmdHints, true, true);
	}
	
	/**Creates logo from file for the program
	 *
	 */
	private void createLogo(Composite parent){
		InputStream stream = getClass().getClassLoader().getResourceAsStream("files/remember4melogo.png"); 
        logo = new Image(parent.getDisplay(), stream);
		//logo = new Image(parent.getDisplay(), "files/remember4melogo.png");
		Label logoLabel = new Label(parent, SWT.NONE);
		logoLabel.setBounds(586, 24, 198, 40);
		toolkit.adapt(logoLabel, true, true);
		logoLabel.setImage(logo);
		//toolkit.adapt(timeLabel, true, true);
	}
	
	/**Creates the legend box to show the main key identifiers available
	 * for command input box
	 *
	 */
	private void createLegendBox(Composite parent){
		Table legendTable = new Table(parent, SWT.NO_SCROLL);
		legendTable.setBackground(SWTResourceManager.getColor(0, 0, 0));
		legendTable.setForeground(SWTResourceManager.getColor(0, 255, 0));
		legendTable.setFont(SWTResourceManager.getFont("Segoe UI", 8, SWT.NORMAL));
		legendTable.setBounds(587, 324, 175, 83);
		//toolkit.adapt(table_1);
		//toolkit.paintBordersFor(table_1);
		
		legendColumns = new TableColumn[4];
	    String[] columntext = {"1","2","3","4"}; 
	    int[] columnsize = {30,60,30,60};
		//create empty table
	    for (int i = 0, n = legendColumns.length; i < n; i++) {
    		legendColumns[i] = new TableColumn(legendTable, SWT.NONE);
    		legendColumns[i].setText(columntext[i]);
    		legendColumns[i].setWidth(columnsize[i]);
		}
	    //fills the table
		for(int i = 0; i < 5; i++) {
			TableItem item = new TableItem(legendTable, SWT.NONE);
			if(i==0) item.setText(new String[] {"+", "add", "#", "DueDate"});
			if(i==1) item.setText(new String[] {"-", "remove", "@", "Time"});
			if(i==2) item.setText(new String[] {"m", "modify", "$", "Venue"});
			if(i==3) item.setText(new String[] {"v", "view", ":", "Label"});
			if(i==4) item.setText(new String[] {"?", "search", "*", "Impt"});
		}
	}
	
	/**Create task count box that show user amount of task in
	 * different categories of tasks
	 *
	 */
	private void createTaskCountBox(final Composite parent){
		ListViewer taskCountViewer = new ListViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL);
		taskCountList = taskCountViewer.getList();
		taskCountList.setBackground(SWTResourceManager.getColor(0, 0, 0));
		taskCountList.setForeground(SWTResourceManager.getColor(255, 255, 255));
		taskCountList.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
		taskCountList.setBounds(587, 229, 175, 66);
		
		Runnable timer = new Runnable() { 
			public void run() {
				//Updates the count every second
				overdueCount = CommandInput.staticInput.getOverdueCount();
				uncompletedCount = CommandInput.staticInput.getUncompletedCount();
				doneCount = CommandInput.staticInput.getDoneCount();
				taskCountList.removeAll();
				taskCountList.add("Tasks Overdue: "+overdueCount, 0);
				taskCountList.add("Tasks Not Done: "+uncompletedCount, 0);
				taskCountList.add("Tasks Completed: "+doneCount, 1);

				parent.getDisplay().timerExec(1000, this);	 
				}
			};
		parent.getDisplay().timerExec(0, timer);	
	}
	
	/**Creates the timer to display real time for user
	 *
	 */
	private void createTimeDisplay(final Composite parent){
		final Label timeLabel = new Label(parent, SWT.NONE);
		final DateFormat timeFormat01 = new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss a");
		
		timeLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
		timeLabel.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		timeLabel.setAlignment(SWT.RIGHT);
		timeLabel.setBounds(599, 0, 206, 14);
		
		Runnable timer = new Runnable() {
			public void run() {
				//Get current time and updates GUI time label
				Calendar curCal = Calendar.getInstance();
				Date curDate = curCal.getTime();
				String curDateFormatted = timeFormat01.format(curDate);
				timeLabel.setText(curDateFormatted); 	//System.out.println("time check");
				//then calls itself again after 1000ms
				parent.getDisplay().timerExec(1000, this);	 
			}
		};
		//Starts the timer straight on GUI init //display.syncExec(timer);
		parent.getDisplay().timerExec(0, timer);	
	}
	
	/**Create the main table that shows the tasks the user should see 
	 * after task actions or upon request
	 *
	 */
	private void createMainTaskDisplay(){
		//set up initial arrangement via column
		comparator = new TaskComparator();
		comparator.setColumn(TaskComparator.DUEDATE);
		comparator.setDirection(TaskComparator.ASCENDING);
		
		 // Create the table
	    mainTaskDisplayTable = new Table(this, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
	    mainTaskDisplayTable.setHeaderVisible(true);
	    mainTaskDisplayTable.setLinesVisible(true);
	    mainTaskDisplayTable.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
	    mainTaskDisplayTable.setBounds(26, 93, 551, 314);
	    toolkit.adapt(mainTaskDisplayTable);
		toolkit.paintBordersFor(mainTaskDisplayTable);
	    // Add Listener(s) to table
	    mainTaskDisplayTable.addSelectionListener(new SelectionAdapter() {
	        public void widgetSelected(SelectionEvent event) {
	        }
	      });
	    mainTaskDisplayTable.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				tableKeyReleaseAction(e);
			}
		});
	    
	    // Create each of the columns, adding an event listener that will 
	    // set the appropriate fields into the comparator and then 
	    // call the fillTable helper method
	    mainTaskDisplayColumns = new TableColumn[8];
	    String[] columntext = {"No.","*","DueDate","Start","Due","Description","Label ","Venue "}; 
	    final int[] columnidx = {0, TaskComparator.IMPORTANCE, TaskComparator.DUEDATE, TaskComparator.START, TaskComparator.DUE,
	    					TaskComparator.DESCRIPTION, TaskComparator.LABEL, TaskComparator.VENUE};
	    int[] columnsize = {20,30,65,40,40,210,70,70};
	    
	    for (int i = 0, n = mainTaskDisplayColumns.length; i < n; i++) {
	    	final int ii = i;
	    	if(i==0){
	    		mainTaskDisplayColumns[i] = new TableColumn(mainTaskDisplayTable, SWT.NONE);
	    		mainTaskDisplayColumns[i].setText(columntext[i]);
			    mainTaskDisplayColumns[i].setWidth(columnsize[i]);
	    	}
	    	else {
	    		mainTaskDisplayColumns[i] = new TableColumn(mainTaskDisplayTable, SWT.NONE);
	    		mainTaskDisplayColumns[i].setText(columntext[i]);
			    mainTaskDisplayColumns[i].setWidth(columnsize[i]);
			    mainTaskDisplayColumns[i].addSelectionListener(new SelectionAdapter() {
				      public void widgetSelected(SelectionEvent event) {
				        comparator.setColumn(columnidx[ii]);
				        comparator.reverseDirection();
				        refreshMTDTable(mainTaskDisplayTable);
				      }
				    });
	    	}
		}
	    // Do the initial fill of the table
	    refreshMTDTable(mainTaskDisplayTable);
	    // Pack each column so initial display is good
	    for (int i = 0, n = mainTaskDisplayColumns.length; i < n; i++) {
	      if(i != 5) mainTaskDisplayColumns[i].pack();
	    }
	}
	
	/**Create a new thread that continuously check for overdue tasks,
	 * and updates the task into correct category as required. Also
	 * implements the alarm/reminder pop up window to get further action from user.
	 *
	 */
	private void beginOverdueCheck(final Shell parent){
		Runnable timer = new Runnable() { 			
			public void run() {				
				// get current time
				Calendar curCal = Calendar.getInstance(); //Date date = new Date();
				//find overdue Tasks
				Task overdueTask = CommandInput.staticInput.getNextTask(); 
				if(overdueTask != null) {
				//determine if next task is overdue
				boolean isOverdue = calCheck(overdueTask, curCal);
				boolean isAlarmOn = overdueTask.isAlarmOn();
				//No alarm is set for task, silent overdue
				if(isOverdue && !isAlarmOn) {
					CommandInput.staticInput.setTaskOverdue(overdueTask);
					refreshView_HM();
					refreshView_MTDTable();
				}
				//Alarm is set for task
				if(isOverdue && isAlarmOn) {
					Toolkit.getDefaultToolkit().beep();
					
					InputDialog alarmDialog = new InputDialog(parent);
	            	alarmDialog.setTaskDescription(overdueTask.getDescription());
	            	alarmDialog.setTaskAttributes("Due: #"+overdueTask.getDateString("ddmmyy")+" "+"@"+
	            								overdueTask.getstrStartTime()+"-"+overdueTask.getstrEndTime());
	            	alarmDialog.setDefaultFields("mod - "+"!on #");
	            	//get response from user via dialog
				    String popupResponse = alarmDialog.open();
				    //reacts to the response
				    if(popupResponse == "Ignore")	{
				    	overdueTask.clearAlarm();
				    	CommandInput.staticInput.setTaskOverdue(overdueTask);
				    }
				    else if(popupResponse == "Done") {
				    	overdueTask.clearAlarm();
				    	CommandInput.staticInput.doneTaskviaPopup(overdueTask);
				    }
				    else {CommandInput.staticInput.modifyTaskviaPopup(popupResponse, overdueTask);}
				    refreshView_HM();
					refreshView_MTDTable();
				}
				}
				//then calls new Runnable again after 1000ms
				parent.getDisplay().timerExec(1000, this);	 
				}
			};
		//Starts the timer straight on GUI init //display.syncExec(timer);
		parent.getDisplay().timerExec(0, timer);	
	}
	
	/**Create a new thread that auto save all tasks at preset intervals
	 *
	 */
	private void beginPeriodicSave(final Composite parent){
		Runnable timer = new Runnable() { 
			boolean saved=false;
			public void run() {				
				Calendar curCal = Calendar.getInstance();
				int min = curCal.get(Calendar.MINUTE);		
				//save once every 2min
				if(min%2 == 0 && !saved) {
					CommandInput.staticInput.parseCmd("save"); 
					CommandInput.staticInput.out().clear();
					saved=true;
				}
				if(min%2!=0) saved=false;
				parent.getDisplay().timerExec(1000, this);	 
				}
			};
		parent.getDisplay().timerExec(0, timer);
	}
	
	/**Action performed when key is released when focus is on the
	 * command input box
	 *
	 */
	private void inputBoxKeyReleasedAction(KeyEvent e) {
		//System.out.println(e.keyCode);
		String userInput = inputCmdBox.getText();
		//System.out.println(userInput);
		String startstr = null;
		String action = null;
		//int oldPt, newPt;
		
		
		if(userInput.length() > 0) {
			startstr = userInput.substring(0,1);
			if(startstr.compareTo("+") == 0) {syntaxHints.setText("+ (*) <Task details> :<label> #<date> @<time> $<venue> !<on|off>"); action = "add";}
			if(startstr.compareTo("-") == 0) {syntaxHints.setText("- id:n"); action = "remove";}
			if(startstr.compareTo("v") == 0) {syntaxHints.setText("v/view | all | upcoming (n) | impt | :<label> | #<date(-date)> | done | overdue | notes"); action = "view";}
			if(startstr.compareTo("m") == 0) {syntaxHints.setText("m/mod <id:n> <title> :<label> #<date> @<time> $<venue> !<on|off>"); action = "modify";}
			if(startstr.compareTo("?") == 0) {syntaxHints.setText("?/search ?"); action = "search";}
			
			if(userInput.length() > 2){
				startstr = userInput.substring(0,3); //can edit title without typing everything again?
				if(startstr.compareTo("mod") == 0) {syntaxHints.setText("mod <id:n> <title> :<label> #<date> @<time> $<venue> !<on|off>"); action = "modify";}
				//oldPt = inputCmdBox.getCaretPosition();
				//inputCmdBox.append("odify");
				//newPt = oldPt+3;
				//inputCmdBox.setSelection(oldPt,oldPt+5);
				
			}
			if(userInput.length() > 3){
				startstr = userInput.substring(0,4); //how to search within a view? 
				if(startstr.compareTo("view") == 0) { 
					syntaxHints.setText("view | all | upcoming (n) | impt | :<label> | #<date(-date)> | done | overdue | notes"); 
					action = "view";
				}
			}
			if(userInput.length() > 3){
				startstr = userInput.substring(0,4); //can fast done on focused task?
				if(startstr.compareTo("done") == 0) {syntaxHints.setText("done <id:n>"); action = "done";}	
			}
			if(userInput.length() > 3){
				startstr = userInput.substring(0,4); //can fast done on focused task?
				if(startstr.compareTo("save") == 0) {syntaxHints.setText("save"); action = "save";}	
			}
			if(userInput.length() > 5){
				startstr = userInput.substring(0,6);
				if(startstr.compareTo("search") == 0) {syntaxHints.setText("search ?"); action = "search";}	
			}
			if(userInput.length() > 5){
				startstr = userInput.substring(0,6);
				if(startstr.compareTo("undone") == 0) {syntaxHints.setText("undone <id:n>"); action = "undone";}	
			}
			if(userInput.length() > 5){
				startstr = userInput.substring(0,6);
				if(startstr.compareTo("import") == 0) {syntaxHints.setText("import"); action = "import";}	
			}
			if(userInput.length() > 5){
				startstr = userInput.substring(0,6);
				if(startstr.compareTo("export") == 0) {syntaxHints.setText("export"); action = "export";}	
			}
		} else {
				syntaxHints.setText("");
				inputCmdBox.setText("What can I do for you? =)");
				inputCmdBox.selectAll();
		}
		
		//when ENTER is pressed and released
		if(e.keyCode == SWT.CR){ 
			if(action != null) {
				modelChangeViaCmdLn();
				refreshView_HM();
				refreshView_MTDTable();
			}
			else{ 
				helperMsgList.removeAll();
				helperMsgList.add("Please check your commands");	//doPrintErr();
			}	
		}
		
		if(e.stateMask == SWT.CTRL && e.keyCode == 'a'){     //selectall 
		      inputCmdBox.selectAll();
		    }
		if(e.keyCode == SWT.ARROW_DOWN ){ //down arrow  //wont work in windows xp
			inputCmdBox.selectAll();
			mainTaskDisplayTable.setFocus();
			mainTaskDisplayTable.setSelection(taskidx);
		}
		
	}
	
	/**Action to be performed when focus is on the table that displays
	 * the tasks the user is viewing
	 *
	 */
	private void tableKeyReleaseAction(KeyEvent e) {
		System.out.println(e.keyCode);
		taskidx = mainTaskDisplayTable.getSelectionIndex();
		if(e.keyCode == 'm') {
	    	int id = mainTaskDisplayTable.getSelectionIndex();
	    	int displayID =  id + 1;
	    	if(id<0) return;
				Task selectedTask = modelOutput_MTD.get(id);
				String selectedTaskstr = selectedTask.printTask_addIdentifier();
				inputCmdBox.setText("mod "+displayID+" "+selectedTaskstr);
				inputCmdBox.selectAll();
				inputCmdBox.setFocus();
		}
		if(e.keyCode == 'd') {
	    	int id = mainTaskDisplayTable.getSelectionIndex();
	    	int displayID =  id + 1;
	    	if(id<0) return;
				inputCmdBox.setText("done "+displayID);
				inputCmdBox.selectAll();
				inputCmdBox.setFocus();
		}
	}

	/**Verify if current time is later than nexttask's time. 
	 * @param nextTask
	 * @param curCal
	 * @return true if so, false if otherwise
	 */
	public boolean calCheck(Task nextTask, Calendar curCal) {
		Calendar nextCal=null;
		if(nextTask != null) {
			nextCal = nextTask.getCal();
	
		/* debugging
		Date nextDate = nextCal.getTime();
		Date curDate = curCal.getTime();
		
		final DateFormat timeFormat02 = new SimpleDateFormat("ddMMyyyy hh:mm:ss"); 
		String nextDateFormatted = timeFormat02.format(nextDate);
		String nextCalFormatted = timeFormat02.format(curDate);
		System.out.println(nextDateFormatted);	
		System.out.println(nextCalFormatted);	
		 */	
			return curCal.after(nextCal);
		}
	else return false;
	}
	
	/**Performs a change in the back end model
	 *
	 */
	public void modelChangeViaCmdLn(){
		String userInput = inputCmdBox.getText();
		inputCmdBox.selectAll();
		//push changes to model
		CommandInput.staticInput.parseCmd(userInput);
	}
	
	/**Performs a update view on the helper message box 
	 * by pulling latest data from the model
	 *
	 */
	public void refreshView_HM(){
		helperMsgList.removeAll();
		modelOutput_HM = CommandInput.staticInput.out();
		
		int size = modelOutput_HM.size();
		for(int i = 0; i < size ; i++){
			String astr = modelOutput_HM.get(i);
			helperMsgList.add(astr);
		}
		modelOutput_HM.clear();
	}
	
	/**Performs a update view on the Main task display Table
	 * by pulling latest data from the model
	 *
	 */
	public void refreshView_MTDTable(){
		modelOutput_MTD = CommandInput.staticInput.outTable();
		
		comparator.setColumn(TaskComparator.DUEDATE);
		comparator.setDirection(TaskComparator.ASCENDING);
		refreshMTDTable(mainTaskDisplayTable);
		
		//select the latest updated task
		taskidx = CommandInput.staticInput.getTaskIndex();
		
		mainTaskDisplayTable.setFocus();
		mainTaskDisplayTable.setSelection(taskidx);
	}
	
	/**Performs refresh on the Main task display table
	 * by updating the table with data from the modeloutput_MTD list
	 * @param table
	 *
	 */
	@SuppressWarnings("unchecked")
	public void refreshMTDTable(Table table) {
	  	 // Turn off drawing to avoid flicker
		table.setRedraw(false);
	  	  
	  	  // We remove all the table entries, sort our rows, then add the entries
	  	  table.removeAll();
	  	  Collections.sort(modelOutput_MTD, comparator);
	  	  System.out.println("From GUI: refreshing table, prints viewListGUI");
	  	  for (Iterator<Task> itr = modelOutput_MTD.iterator(); itr.hasNext();) {
	  	      Task aTask = (Task) itr.next();
	  	      System.out.println(aTask.printTask());
	  	      
	  	      TableItem item = new TableItem(table, SWT.NONE);
	  	      int c = 0;
	  	      String id = Integer.toString(modelOutput_MTD.indexOf(aTask)+1);
	  	      
	  	  String str_newDate = aTask.getDateString("ddmmyy");
	  	  String str_newStartTime = aTask.getstrStartTime();
	  	  String str_newEndTime = aTask.getstrEndTime();
	  
  	      item.setText(c++, id);
  	      item.setText(c++, (aTask.hasImportance()) ? "*":"" );
  	      item.setText(c++, str_newDate);
  	      item.setText(c++, str_newStartTime);
  	      item.setText(c++, str_newEndTime);
  	      item.setText(c++, aTask.getDescription());
  	      item.setText(c++, aTask.getLabel());
  	      item.setText(c++, aTask.getVenue());
	  	  }
	  	  
	  	  System.out.println("------------");
	  	  for (int i = 0, n = mainTaskDisplayColumns.length; i < n; i++) {
	  		  if(i != 5) mainTaskDisplayColumns[i].pack();
	  	  }
	  	  // Turn drawing back on
	  	  table.setRedraw(true);
	  }
}
